﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;

namespace TrackTool
{
    class TrainLocData
    {
        public List<ItemSafeRoute> morninglist = new List<ItemSafeRoute>();
        public List<ItemSafeRoute> noonlist = new List<ItemSafeRoute>();
        public List<ItemSafeRoute> nightlist = new List<ItemSafeRoute>();


        public int ReadRoute(MemoryStream ms)
        {
            int nRet = 0;
            ms.Seek(0, SeekOrigin.Begin);
            UInt32 crc1 = ReadUInt32(ms);
            UInt32 crc2 = CalcFileCRC32(ms);
            if (crc1 != crc2)
            {
                Console.Out.Write("crc error!");
                return 0;
            }

            morninglist.Clear();
	        noonlist.Clear();
	        nightlist.Clear();

	        ms.Seek(4, SeekOrigin.Begin);

	        //读取morninglist的长度 2字节
	        ushort l1size = ReadUShort(ms);
	        //读取ItemSafeRoute对象
	        for (int i = 0; i < l1size; i++)
	        {
		        ItemSafeRoute item = ReadItemSafeRouteObj(ms);
		        morninglist.Add(item);
	        }

	        //读取noonlist的长度 2字节
	        ushort l2size = ReadUShort(ms);
	        //读取ItemSafeRoute对象
	        for (int i = 0; i < l2size; i++)
	        {
                ItemSafeRoute item = ReadItemSafeRouteObj(ms);
		        noonlist.Add(item);
	        }

	        //读取nightlist的长度 2字节
	        ushort l3size = ReadUShort(ms);
	        //读取ItemSafeRoute对象
	        for (int i = 0; i < l3size; i++)
	        {
		        ItemSafeRoute item = ReadItemSafeRouteObj(ms);
                nightlist.Add(item);
	        }


            return 1;
        }

        ItemSafeRoute ReadItemSafeRouteObj(MemoryStream ms)
        {
            UInt32 flag = ReadUInt32(ms);
	        if(flag != 0xBBBBBBBB)
                return null;

            ItemSafeRoute item = new ItemSafeRoute();

	        //读取spt,ept
	        item.spt = ReadBasicLocItemObj(ms);
	        item.ept = ReadBasicLocItemObj(ms);

	        //读取list大小 2字节
	        ushort size = ReadUShort(ms);
	        for (int i = 0; i < size; i++)
	        {
		        BASIC_LOC_ITEM obj = ReadBasicLocItemObj(ms);
                if (item.list == null)
                    item.list = new List<BASIC_LOC_ITEM>();
		        item.list.Add(obj);
	        }

	        //读取mergeCount
            item.mergeCount = ReadInt32(ms);

            return item;
        }

        BASIC_LOC_ITEM ReadBasicLocItemObj(MemoryStream ms)
        {
	        UInt32 flag = ReadUInt32(ms);
	        if(flag != 0xAAAAAAAA)
                return null;

            BASIC_LOC_ITEM item = new BASIC_LOC_ITEM();
	        double lat = ReadDouble(ms);
            double lng = ReadDouble(ms);
            if (lat > 0 && lng > 0)
            {
                double[] dd = GeoConvert.encrypt(lat, lng);
                item.lat = dd[0];
                item.lng = dd[1];
            }
            else
            {
                item.lat = 0;
                item.lng = 0;
            }
            

            long tTime = ReadInt64(ms);
            item.tTime = new DateTime(tTime * 1000);
            long tEndTime = ReadInt64(ms);
            item.tEndTime = new DateTime(tEndTime * 1000);
	        
            LAC_CID cid = new LAC_CID();
            cid.mnc = ReadInt32(ms);
            cid.lac = ReadUInt32(ms);
            cid.cid = ReadUInt32(ms);
            item.cid = cid;

	        item.weight = ReadInt32(ms);
	        item.radius = ReadInt32(ms);

	        ushort cidlistsize = ReadUShort(ms);
	        for (int i = 0; i < cidlistsize; i++)
	        {
		        LAC_CID lc = new LAC_CID();
                cid.mnc = ReadInt32(ms);
                cid.lac = ReadUInt32(ms);
                cid.cid = ReadUInt32(ms);
                if (item.cidlist == null)
                    item.cidlist = new List<LAC_CID>();
		        item.cidlist.Add(lc);
	        }

            return item;
        }
        public UInt32 CalcFileCRC32(MemoryStream ms)
        {
            ms.Seek(4, SeekOrigin.Begin);
            byte[] buf = new byte[ms.Length-4];
            ms.Read(buf, 0, buf.Length);
            UInt32 crc = CRC32.GetCRC32(buf);
            return crc;
        }

        private Int32 ReadInt32(MemoryStream ms)
        {
            byte[] buff = new byte[4];
            ms.Read(buff, 0, 4);
            Int32 ret = System.BitConverter.ToInt32(buff, 0);
            return ret;
        }

        private UInt32 ReadUInt32(MemoryStream ms)
        {
            byte[] buff = new byte[4];
            ms.Read(buff, 0, 4);
            UInt32 ret = System.BitConverter.ToUInt32(buff, 0);
            return ret;
        }

        private long ReadInt64(MemoryStream ms)
        {
            byte[] buff = new byte[8];
            ms.Read(buff, 0, 8);
            long ret = System.BitConverter.ToInt64(buff, 0);
            return ret;
        }

        private ushort ReadUShort(MemoryStream ms)
        {
            byte[] buff = new byte[2];
            ms.Read(buff, 0, 2);
            ushort ret = System.BitConverter.ToUInt16(buff, 0);
            return ret;
        }

        private double ReadDouble(MemoryStream ms)
        {
            byte[] buff = new byte[8];
            ms.Read(buff, 0, 8);
            double ret = System.BitConverter.ToDouble(buff, 0);
            return ret;
        }
    }
}
